因為工作關係必須透過IPHONE跟藍牙(4.0)做溝通,並且藍芽後面還接著一顆MCU,因此就湊巧又回頭碰Struct
- Struct & Union
- Pragma pack
- 結構初始化
- :
- Union 認識
其他相關網站
Struct & Union
取自:史丹利部落格
為了解決從MCU透過藍牙傳遞過來的資料
遇到封包裡不同的OPCODE
採取的封包解析也相對應不同
Struct & Union1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| struct structA { int a; char b; };
struct structB { char a; short b; };
struct structC { int a; char b; float c; }
struct CommuPacket { int iPacketType; union { struct structA packetA; struct structB packetB; struct structC packetC; }; };
switch(recvCommuPacket.iPacketType) { case PACKET_A: … break; case PACKET_B: … break; case PACKET_C: … break; }
|
pragma pack(n)
同樣取自:史丹利部落格
自然對界
struct是一種複合資料類型,其構成元素既可以是基本資料類型(如int、long、float等)的變數,也可以是一些複合資料類型(如array、struct、union等)的資料單元。對於結構體,編譯器會自動進行成員變數的對齊,以提高運算效率。缺省情況下,編譯器為結構體的每個成員按其自然對界(natural alignment)條件分配空間。各個成員按照它們被聲明的順序在記憶體中順序存儲,第一個成員的位址和整個結構的位址相同。
自然對界(natural alignment)即默認對齊方式,是指按結構體的成員中size最大的成員對齊。
指定對界
一般地,可以通過下面的方法來改變缺省的對界條件:
- 使用虛擬指令
#pragma pack(n)
,編譯器將按照n個位元組對齊;
- 使用虛擬指令
#pragma pack()
,取消自定義位元組對齊方式。
注意:如果#pragma pack (n)
中指定的n大於結構體中最大成員的size,則其不起作用,結構體仍然按照size最大的成員進行對界。
pragma pack(n)1 2 3 4 5 6 7
| #pragma pack(n) struct naturalalign { char a; int b; char c; };
|
結構初始化
C的結構是能夠在初始化時,個別給值滴
在這篇有提到,該如何個別給值
C: Structure Initialization (Advanced)
Structure Initialization (Advanced)1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| struct student {
int roll;
int class;
char name[50];
};
student st3={1038,10,"Mark"};
student st3={
.name = "Mark",
.class = 10,
.roll = 1038
};
|
:
接著是『:
』,映象中以前沒用過:
Structures Nested Inside Unions
:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| typedef union { struct { uint8_t a:1; uint8_t b:1; uint8_t c:1; uint8_t d:1;
uint8_t e:1; uint8_t f:1; uint8_t g:1; uint8_t h:1; } items; uint8_t yy; uint8_t zz; } typeName_t;
typeName_t t; t.yy = 0xc0;
t.items.a = 1;
t.items.c = 1;
t.items.g = 0;
|
Union 認識
另外是對union有多一點的認識
Union 練習1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| #pragma pack(1) typedef struct parameter{ uint8_t deviceID; uint8_t versionPre; uint8_t versionSuffix; uint8_t dataType; }parameter;
#pragma pack(1) typedef struct setting{ uint8_t deviceID; uint8_t versionPre; uint8_t versionSuffix; uint8_t dataType; uint8_t dataType1; uint8_t dataType2; }setting;
#pragma pack(1) typedef struct{ int32_t len;
union { setting s; parameter p; };
union{ uint8_t secret; int digest; }; }fileData;
parameter p = {1,2,3,4}; setting s = {5,6,7,8,9,10};
fileData f1 = {1,.p=p,.secret=11};
fileData f2 = {2,.s=s,.secret=12};
|